import React, {
  CSSProperties,
  forwardRef,
  HTMLAttributes,
  InputHTMLAttributes,
  MouseEventHandler,
  Reducer,
  useEffect,
  useImperativeHandle,
  useLayoutEffect,
  useReducer,
  useRef,
  ComponentProps,
} from "react";

const Test = () => {
  const hRef = useRef<HTMLHeadingElement>(null);
  const testRef = useRef<{ num: number }>({ num: 23 });
  const sonRef = useRef<HTMLDivElement>(null);
  const son2Ref = useRef<Son2Ref>({ aaa: () => {} });
  useEffect(() => {
    testRef.current.num = 23;
  });

  useLayoutEffect(() => {
    console.log(son2Ref.current, "son2Ref");
  });
  return (
    <>
      <h1>{testRef.current.num}</h1>
      <h1 ref={hRef}>Test</h1>
      <Son
        name="son component"
        content={<p style={{ color: "red" }}>content</p>}
      ></Son>

      <WrapSon ref={sonRef}></WrapSon>

      <WrapSon2 ref={son2Ref} test="test"></WrapSon2>

      <hr />
      <Son3 color="purple">
        <div>i am children</div>
      </Son3>

      <hr />
      <Son4 clickHandler={(e) => {}}></Son4>

      <hr />

      <Son5
        onChange={(e) => {
          //   e.target.aaaa;
        }}
      ></Son5>
    </>
  );
};
type SonProps = {
  name: string;
  //   content: JSX.Element;
  //   content: React.ReactElement; // 类型范围：React.ReactNode > React.ReactElement >JSX.Element
  content: React.ReactNode;
};
// type React.FunctionComponent<SonProps> = React.FC<SonProps>;
const Son: React.FC<SonProps> = (props, ref) => {
  return (
    <div>
      <p>{props.name}</p>
      {props.content}
    </div>
  );
};

const Son1: React.ForwardRefRenderFunction<HTMLDivElement, {}> = (
  props,
  ref
) => {
  return <div ref={ref}>son1</div>;
};
interface Son2Ref {
  aaa: () => void;
}
const Son2: React.ForwardRefRenderFunction<Son2Ref, { test: string }> = (
  props,
  ref
) => {
  useImperativeHandle(ref, () => {
    return {
      aaa: () => {
        return props.test;
      },
    };
  });
  return <div>son2</div>;
};

const WrapSon = forwardRef(Son1);
const WrapSon2 = forwardRef(Son2);

interface Data {
  result: number;
}

interface Action {
  type: "add" | "minus";
  num: number;
}
interface Son3Props {
  children?: React.ReactNode;
  color?: CSSProperties["color"];
}

type Son3Props2 = React.PropsWithChildren<Son3Props>;

const Son3 = (props: Son3Props2) => {
  const reducer = (state: Data, action: Action) => {
    switch (action.type) {
      case "add":
        return { result: state.result + action.num };
      case "minus":
        return { result: state.result - action.num };
      default:
        return state;
    }
  };
  const [res, dispatch] = useReducer<Reducer<Data, Action>, { result: number }>(
    reducer,
    {
      result: 1,
    },
    (param) => {
      return {
        result: param.result + 100,
      };
    }
  );
  return (
    <div style={{ color: props.color }}>
      <p>{res.result}</p>
      <button onClick={() => dispatch({ type: "add", num: 1 })}>+</button>
      <button onClick={() => dispatch({ type: "minus", num: 1 })}>-</button>
      {props.children}
    </div>
  );
};

interface EventHandler {
  clickHandler: MouseEventHandler<HTMLDivElement>;
}

const Son4 = (props: EventHandler) => {
  return <div onClick={props.clickHandler}>son4</div>;
};

interface Son5Props extends InputHTMLAttributes<{ aaaa: string }> {}

const Son5 = (props: Son5Props) => {
  return <div>son5</div>;
};

// let a:ComponentProps<'a'> = 'a'

export default Test;
